
// Copyright (C) 2010-2011 Luca Piccioni
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//  
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//  
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Diagnostics;

using Derm.OpenGL;

namespace Derm.Render
{
	/// <summary>
	/// Polygon state
	/// </summary>
	public class PolygonState : RenderState
	{
		#region Constructors and Destructor
		
		/// <summary>
		/// BlendRenderState constructor.
		/// </summary>
		public PolygonState() : base(StateID)
		{
			
		}
		
		#endregion
		
		#region Face State Definition

		/// <summary>
		/// Polygon face rasterization modes.
		/// </summary>
		public enum RasterFace
		{
			/// <summary>
			/// Rasterized polygons are rendered as points.
			/// </summary>
			Points,
			/// <summary>
			/// Rasterized polygons are rendered as lines.
			/// </summary>
			Lines,
			/// <summary>
			/// Rasterized polygons are rendered filled.
			/// </summary>
			Fill
		}

		/// <summary>
		/// 
		/// </summary>
		public RasterFace RasterFaceMode
		{
			get {
				switch (mRasterFaceMode) {
				case Gl.POINT:
					return (RasterFace.Points);
				case Gl.LINE:
					return (RasterFace.Lines);
				case Gl.FILL:
					return (RasterFace.Fill);
				default:
					return (RasterFace.Fill);
				}
			}
			set {
				switch (value) {
				case RasterFace.Points:
					mRasterFaceMode = Gl.POINT;
					break;
				case RasterFace.Lines:
					mRasterFaceMode = Gl.LINE;
					break;
				case RasterFace.Fill:
					mRasterFaceMode = Gl.FILL;
					break;
				}
			}
		}

		/// <summary>
		/// Polygon face rasterization mode.
		/// </summary>
		private int mRasterFaceMode = Gl.FILL;
		
		#endregion
		
		#region RenderState Implementation

		/// <summary>
		/// The name of this render context.
		/// </summary>
		public static readonly string StateID = "Face";
		
		/// <summary>
		/// Apply this blend renderer state.
		/// </summary>
		/// <param name="ctx">
		/// A <see cref="RenderContext"/> which has defined the shader program <paramref name="sProgram"/>.
		/// </param>
		/// <param name="sProgram">
		/// The <see cref="ShaderProgram"/> which has the state set.
		/// </param>
		/// <remarks>
		/// <para>
		/// Apply this renderer state to the rendering context. This routine doesn't backup
		/// the previously values set, indeed cannot restore previous rendering attribute value.
		/// </para>
		/// <para>
		/// It's advisable to call this method only when is really necessary to change the renderer
		/// state, and to minimize state changes since they influence deeply the rendering
		/// pipeline performances.
		/// </para>
		/// </remarks>
		public override void ApplyState(RenderContext ctx, ShaderProgram sProgram)
		{
			// Polygon rasterization
			Gl.PolygonMode(Gl.FRONT_AND_BACK, mRasterFaceMode);
			Debug.Assert(RenderException.CheckErrors() == true);
		}

		/// <summary>
		/// Determine whether this RenderState is defined on server side.
		/// </summary>
		/// <remarks>
		/// This RenderState modify the OpenGL internal state.
		/// </remarks>
		public override bool ServerSide { get { return (true); } }

		/// <summary>
		/// Determine whether this RenderState is inherited.
		/// </summary>
		/// <remarks>
		/// This RenderState is inheritable.
		/// </remarks>
		public override bool Inheritable { get { return (true); } }
		
		#endregion
	}
}
